package com.ibeeking.found.msg.rest.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.ibeeking.found.common.entity.msg.WxMpMassMsgSendParam;
import com.ibeeking.found.common.entity.msg.WxMpTemplateMaPagePath;
import com.ibeeking.found.common.entity.msg.WxMpTemplateMsgSendParam;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.msg.api.feign.MsgMemberCClient;
import com.ibeeking.found.msg.rest.service.IOpenService;
import com.ibeeking.found.msg.rest.service.ISendWxMpMsgService;
import com.ibeeking.found.msg.rest.service.IWxMpFansService;
import com.ibeeking.found.msg.rest.service.IWxMpMsgTemplateService;
import com.ibeeking.found.msg.service.common.param.MsgNoticeParam;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseCodeEnum;
import com.ibeeking.nematos.utils.result.ResponseResult;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMassMessageService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpTemplateMsgService;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @ClassName SendSmsServiceImpl
 * @Description 发送短信实现类
 * @Author ibeeking
 * @Date 2020-12-10 9:21
 **/
@Service
public class SendWxMpMsgServiceImpl implements ISendWxMpMsgService {

    @Resource
    private IOpenService wxOpenServiceImpl;

    @Resource
    private MsgMemberCClient msgMemberCClient;

    @Resource
    private IWxMpFansService wxMpFansServiceImpl;

    @Resource
    private IWxMpMsgTemplateService templateMsgServiceImpl;

    @Override
    public Boolean sendWxMpTemplateMessage(Integer tenantId, String templateCode, List<String> toUser, Map<String, String> paramMap) throws WxErrorException {
        if (StringUtils.isEmpty(templateCode) || CollUtil.isEmpty(paramMap) || Collections3.isEmpty(toUser)) {
            return false;
        }
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(Long.valueOf(tenantId));
        WxMpTemplateMsgService msgService = wxMpService.getTemplateMsgService();
        String appid = wxMpService.getWxMpConfigStorage().getAppId();
        WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
        templateMessage.setTemplateId(templateCode);
        templateMessage.setToUser(toUser.get(0));

        List<WxMpTemplateData> data = new ArrayList<>();
        for (Map.Entry<String, String> item : paramMap.entrySet()) {
            WxMpTemplateData itemData = new WxMpTemplateData();
            itemData.setName(item.getKey());
            itemData.setValue(item.getValue());
            data.add(itemData);
        }
        templateMessage.setData(data);
        LogUtils.info(">>>>>>>>>>>sendWxMpTemplateMessage templateMessage:{}",JsonUtils.toJsonStr(templateMessage));
        msgService.sendTemplateMsg(templateMessage);
        return true;
    }

    @Override
    public Boolean sendWxMpMassMessage(MsgNoticeParam param) {
        WxMpMassMsgSendParam news = JsonUtils.fromJson(param.getContent(), WxMpMassMsgSendParam.class);
        //参数校验
        if (checkWxMpMassMessageParam(news)) {
            return true;
        }
        //查询接收者openId
        List<String> openIds = news.getToUserOpenIds();
        if (Collections3.isEmpty(openIds)) {
            openIds = queryOpenIds(news.getFansIds());
            if (null == openIds) {
                return false;
            }
            if (Collections3.isEmpty(openIds)) {
                return true;
            }
        }
        Long tenantId = UserUtils.getTenantID();
        //查询公众号配置
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(tenantId);
        WxMpMassMessageService massMessageService = wxMpService.getMassMessageService();
        WxMpMassOpenIdsMessage wxMpMassOpenIdsMessage = new WxMpMassOpenIdsMessage();
        wxMpMassOpenIdsMessage.setClientMsgId(news.getClientMsgId());
        wxMpMassOpenIdsMessage.setContent(news.getContent());
        wxMpMassOpenIdsMessage.setMediaId(news.getMediaId());
        wxMpMassOpenIdsMessage.setMsgType(news.getMsgType());
        wxMpMassOpenIdsMessage.setToUsers(openIds);
        try {
            WxMpMassSendResult wxMpMassSendResult = massMessageService.massOpenIdsMessageSend(wxMpMassOpenIdsMessage);
        } catch (WxErrorException e) {
            throw new BusinessException("发送模板消息失败：" + e.getError().getErrorMsg(), e);
        }
        return true;
    }

    @Override
    public Boolean sendWxMpSimpleMessage(MsgNoticeParam param) {
        WxMpTemplateMsgSendParam msg = JsonUtils.fromJson(param.getContent(), WxMpTemplateMsgSendParam.class);
        //参数校验
        if (checkWxMpTemplateMessageParam(msg)) {
            return true;
        }
        //查询接收者openId
        String toUserOpenId = msg.getToUserOpenId();
        if (StringUtils.isBlank(toUserOpenId)) {
            toUserOpenId = queryOpenId(msg.getFansId());
            if (null == toUserOpenId) {
                return false;
            }
            if (StringUtils.isBlank(toUserOpenId)) {
                return true;
            }
        }
        //根据模板id查询微信模板id
        String templateId = msg.getWxTemplateId();
        if (StringUtils.isBlank(templateId)) {
            String templateInfo = templateMsgServiceImpl.queryTemplateIdById(msg.getTemplateId());
            if (StringUtils.isNotBlank(templateInfo)) {
                templateId = templateInfo;
            } else {
                return true;
            }
        }

        //查询公众号配置
        Long tenantId = UserUtils.getTenantID();
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(tenantId);
        WxMpTemplateMsgService templateMsgService = wxMpService.getTemplateMsgService();
        WxMpTemplateMessage message = new WxMpTemplateMessage();
        message.setToUser(toUserOpenId);
        message.setTemplateId(templateId);
        if (StringUtils.isNotBlank(msg.getUrl())) {
            message.setUrl(msg.getUrl());
        }
        if (null != msg.getMiniProgram()) {
            WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
            miniProgram.setAppid(msg.getMiniProgram().getAppId());
            miniProgram.setPagePath(msg.getMiniProgram().getPagePath());
            message.setMiniProgram(miniProgram);
        }
        List<WxMpTemplateData> data = new ArrayList<>();
        msg.getData().stream().forEach(s -> data.add(new WxMpTemplateData(s.getName(), s.getValue(), s.getColor())));
        message.setData(data);
        try {
            String s = templateMsgService.sendTemplateMsg(message);
        } catch (WxErrorException e) {
            throw new BusinessException("发送模板消息失败：" + e.getError().getErrorMsg(), e);
        }
        return true;
    }

    /**
     * 参数校验
     *
     * @param param
     * @return
     */
    private Boolean checkWxMpTemplateMessageParam(WxMpTemplateMsgSendParam param) {
        if (null == param.getAppId()) {
            LogUtils.warn("公众号必选:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }

        if (null == param.getTemplateId() && StringUtils.isBlank(param.getWxTemplateId())) {
            LogUtils.warn("公众号消息模板必选:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }

        if (null == param.getFansId() && StringUtils.isBlank(param.getToUserOpenId())) {
            LogUtils.warn("接收人必填:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }

        if (null != param.getMiniProgram()) {
            WxMpTemplateMaPagePath miniProgram = param.getMiniProgram();
            if (StringUtils.isBlank(miniProgram.getAppId())) {
                LogUtils.warn("小程序必选:[{}]", JsonUtils.toJsonStr(param));
                return true;
            }
            if (StringUtils.isBlank(miniProgram.getPagePath())) {
                LogUtils.warn("小程序跳转页面必填:[{}]", JsonUtils.toJsonStr(param));
                return true;
            }
        }

        if (Collections3.isEmpty(param.getData())) {
            LogUtils.warn("模板数据必填:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        return false;
    }

    /**
     * 参数校验
     *
     * @param param
     * @return
     */
    private Boolean checkWxMpMassMessageParam(WxMpMassMsgSendParam param) {
        if (null == param.getAppId()) {
            LogUtils.warn("公众号必选:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        if (Collections3.isEmpty(param.getFansIds()) && Collections3.isEmpty(param.getToUserOpenIds())) {
            LogUtils.warn("群发接收人必选:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        if (Collections3.isNotEmpty(param.getFansIds()) && param.getFansIds().size() == 1) {
            LogUtils.warn("群发接收人至少2个:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        if (Collections3.isNotEmpty(param.getToUserOpenIds()) && param.getToUserOpenIds().size() == 1) {
            LogUtils.warn("群发接收人至少2个:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        if (StringUtils.isBlank(param.getMsgType())) {
            LogUtils.warn("群发消息类型必填:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        if (!WxConsts.MassMsgType.IMAGE.equals(param.getMsgType()) && !WxConsts.MassMsgType.MPNEWS.equals(param.getMsgType()) && !WxConsts.MassMsgType.TEXT.equals(param.getMsgType()) && !WxConsts.MassMsgType.MPVIDEO.equals(param.getMsgType()) && !WxConsts.MassMsgType.VOICE.equals(param.getMsgType())) {
            LogUtils.warn("群发消息类型不支持:[{}]", JsonUtils.toJsonStr(param));
            return true;
        }
        return false;
    }

    /**
     * 查询openId
     *
     * @param memberId
     * @return
     */
    private String queryOpenId(Long memberId) {
        //通过会员id查询会员的mpUnionId
        ResponseResult<List<String>> responseResult = msgMemberCClient.queryUnionIds(Collections.singletonList(memberId));
        if (null != responseResult && ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode())) {
            if (Collections3.isNotEmpty(responseResult.getData())) {
                //通过mpUnionId和公众号id查询openId
                List<String> openIds = wxMpFansServiceImpl.queryOpenIds(Collections.singletonList(responseResult.getData().get(0)));
                if (Collections3.isNotEmpty(openIds)) {
                    return openIds.get(0);
                } else {
                    LogUtils.warn("查询会员OpenId[{}]失败", memberId);
                    return "";
                }
            } else {
                LogUtils.warn("查询会员[{}]信息不存在", memberId);
                return "";
            }
        } else {
            LogUtils.warn("查询会员[{}]信息失败", memberId);
            return null;
        }
    }
    /**
     * 查询openId列表
     *
     * @param fansIds
     * @return
     */
    private List<String> queryOpenIds(List<Long> fansIds) {
        //通过会员id查询会员的mpUnionId
        ResponseResult<List<String>> responseResult = msgMemberCClient.queryUnionIds(fansIds);
        if (null != responseResult && ResponseCodeEnum.SUCCESS.getCode().equals(responseResult.getCode())) {
            if (Collections3.isNotEmpty(responseResult.getData())) {
                //通过mpUnionId和公众号id查询openId
                return wxMpFansServiceImpl.queryOpenIds(responseResult.getData());
            } else {
                LogUtils.warn("查询会员[{}]信息不存在", fansIds.toString());
                return Collections3.emptyList();
            }
        } else {
            LogUtils.warn("查询会员[{}]信息失败", fansIds.toString());
            return null;
        }
    }

}
